﻿using System.Windows.Forms;
using System;
using System.Data;
using System.ComponentModel;
using System.Linq;
using DevExpress.XtraEditors;
using Mota.EditModule;
using System.Collections.Generic;

namespace Mota.XMLControls
{
    /// <summary>
    /// Represent TreeView control based on my DBTreeView inherited from Base WinForms TreeView
    /// </summary>
    public class DXGuiTreeView : GuiTreeView
    {
        private DBTreeView dbTree = new DBTreeView();
        private CheckEdit cbIsRootNode = new CheckEdit();
        private object valueToRestore = null;
        /// <summary>
        /// Create DBTreeView instance
        /// Set AutoBuildTree and HideSelection to false
        /// </summary>
        public DXGuiTreeView()
        {
            dbTree.AutoBuildTree = false;
            dbTree.HideSelection = false;
            dbTree.Dock = DockStyle.Fill;
            var gc = new GroupControl();
            visualControl = gc;
            gc.Controls.Add(dbTree);
            // hide caption of the group control by default
            gc.ShowCaption = false;
            cbIsRootNode.Text = "Is Root Node";
            cbIsRootNode.Dock = DockStyle.Top;
            cbIsRootNode.Checked = false;
            cbIsRootNode.CheckedChanged += cbIsRootNode_CheckedChanged;
            gc.Controls.Add(cbIsRootNode);


        }

        void cbIsRootNode_CheckedChanged(object sender, EventArgs e)
        {
            if ((sender as CheckEdit).Checked)
            {
                dbTree.Enabled = false;
                resetValue();
            }
            else
            {
                dbTree.Enabled = true;
                restoreValue();
            }
        }

        /// <summary>
        /// Set|Get  DBTreeView Text property
        /// </summary>
        public override string Text
        {
            get
            {
                return (visualControl as GroupControl).Text;
            }
            set
            {
                (visualControl as GroupControl).Text = value;
            }
        }

        /// <summary>
        /// Get| Set DataSource to build tree structure
        /// </summary>
        public override object Binding
        {
            get
            {
                return dbTree.DataSource;
            }
            set
            {
                if (value is BindingSource)
                {

                    dbTree.DataSource = value;
                    //TODO: may couse the error
                    dbTree.ValueMember = XmlAttributes["_KeyField"];
                    var DisplayField = XmlAttributes["_Fields"].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Last();
                    dbTree.DisplayMember = DisplayField;
                    dbTree.ParentMember = XmlAttributes["_ParentKeyField"];
                    dbTree.BuildTree();
                }
            }
        }
        /// <summary>
        /// Apply value to DBTreeView to select specific node by current record value
        /// </summary>
        /// <param name="valueBinding">main binding with current record values</param>
        public override void SetValue(object valueBinding)
        {
            if (dbTree.DataSource != null)
            {
                //TODO:correct to right way for storing valueBinding
                dbTree.Tag = valueBinding;
                CurrencyManager cm = (valueBinding as BindingSource).CurrencyManager;
                PropertyDescriptor pdValue = cm.GetItemProperties()[XmlAttributes["XMLAttribute"]];
                if (pdValue != null)
                {
                    object currValue = pdValue.GetValue(cm.Current);
                    TreeNode curNode = dbTree.FindNodeByValue(currValue);
                    if (curNode != null)
                    {
                        dbTree.SelectedNode = curNode;
                    }
                    else
                    {
                        cbIsRootNode.Checked = true;
                    }
                    dbTree.AfterSelect += new TreeViewEventHandler(tv_AfterSelect);
                }
            }
        }
        /// <summary>
        /// event handler on after select DBTreeView node
        /// to write value into main binding value
        /// </summary>
        /// <param name="sender">sender</param>
        /// <param name="e">TreeViewEventArgs</param>
        void tv_AfterSelect(object sender, TreeViewEventArgs e)
        {
            CurrencyManager cm = (dbTree.Tag as BindingSource).CurrencyManager;
            PropertyDescriptor pdValue = cm.GetItemProperties()[XmlAttributes["XMLAttribute"]];
            if (pdValue != null)
            {
                pdValue.SetValue(cm.Current, (e.Node as DBTreeNode).NodeValue);
            }
            this.ChangeEventCall(null);
        }
        void resetValue()
        {
            CurrencyManager cm = (dbTree.Tag as BindingSource).CurrencyManager;
            PropertyDescriptor pdValue = cm.GetItemProperties()[XmlAttributes["XMLAttribute"]];
            if (pdValue != null)
            {
                valueToRestore = pdValue.GetValue(cm.Current);
                pdValue.ResetValue(cm.Current);
            }
        }
        void restoreValue()
        {
            CurrencyManager cm = (dbTree.Tag as BindingSource).CurrencyManager;
            PropertyDescriptor pdValue = cm.GetItemProperties()[XmlAttributes["XMLAttribute"]];
            if ((pdValue != null) && (valueToRestore != null))
            {
                pdValue.SetValue(cm.Current, valueToRestore);
            }
        }

        public override void Refresh(ConnectionConfigs configs, BindingSource mainBs)
        {
            this.Rfsh(mainControls, mainBs, configs);
        }

        public override object GetValue()
        {
            CurrencyManager cm = (dbTree.Tag as BindingSource).CurrencyManager;
            PropertyDescriptor pdValue = cm.GetItemProperties()[XmlAttributes["XMLAttribute"]];
            if (pdValue != null)
            {
                return pdValue.GetValue(cm.Current);
            }
            else
            {
                return null;
            }
        }
    }
}
